package cn.cas.mango.util;

import io.swagger.models.auth.In;
import org.apache.commons.math3.linear.ArrayRealVector;
import org.apache.commons.math3.linear.RealVector;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Matrix {

  // 计算两个向量之间的余弦相似度
  private static double cosineSimilarity(double[] vec1, double[] vec2) {
    RealVector v1 = new ArrayRealVector(vec1);
    RealVector v2 = new ArrayRealVector(vec2);
    return v1.dotProduct(v2) / (v1.getNorm() * v2.getNorm());
  }

  // 计算两个向量之间的余弦相似度
  public static double cosineSimilarity(List<Double> list1, List<Double> list2) {
    if (list1 == null || list1.isEmpty() || list2 == null || list2.isEmpty()) return 0;
    double[] array1 = list1.stream().mapToDouble(Double::doubleValue).toArray();
    double[] array2 = list2.stream().mapToDouble(Double::doubleValue).toArray();

    double v = cosineSimilarity(array1, array2);
    return v;
  }

  private static List<Double> checkDoubleItem(List<Double> doubles, int lens) {
    List<Double> ret = new ArrayList<>();
    if (doubles == null || doubles.isEmpty()) {
      for (int j = 0; j < lens; j++) {
        ret.add(0.000000001);
      }
    } else {
      return doubles;
    }
    return ret;
  }


  private static List<List<Double>> checkDouble(List<List<Double>> list, int lens) {
    List<List<Double>> result = new ArrayList<>();
    for (List<Double> doubles : list) {
      result.add(checkDoubleItem(doubles, lens));
    }
    return result;
  }

  public static List<Double> getAvg(List<List<Double>> list, Integer vectorSize) {
    int lens = vectorSize;
    List<Double> ret = new ArrayList<>();
    list = checkDouble(list, lens);
    for (int j = 0; j < lens; j++) {
      double all = 0;
      for (int i = 0; i < list.size(); i++) {
        all += list.get(i).get(j);
      }
      ret.add(all / list.size());
    }
    return ret;
  }

  public static void main(String[] args) {
    double[] vec1 = {1, 2, 3};
    double[] vec2 = {4, 5, 6};

    double similarity = cosineSimilarity(vec1, vec2);
    System.out.println("两个向量之间的余弦相似度为: " + similarity);
  }
}
